package persistence

import (
	"context"
	"errors"
	"fmt"
	"strings"
	"time"

	"baseService/internal/pkg/logger"

	"gorm.io/gorm"
	gormLogger "gorm.io/gorm/logger"
	"gorm.io/gorm/utils"
)

// GormLogger GORM 日志器 - 更好地集成 zap
type GormLogger struct {
	logger                    logger.Logger
	LogLevel                  gormLogger.LogLevel
	SlowThreshold             time.Duration
	IgnoreRecordNotFoundError bool
}

// NewGormLogger 创建 GORM 日志器
func NewGormLogger(l logger.Logger, config gormLogger.Config) *GormLogger {
	return &GormLogger{
		logger:                    l,
		LogLevel:                  config.LogLevel,
		SlowThreshold:             config.SlowThreshold,
		IgnoreRecordNotFoundError: config.IgnoreRecordNotFoundError,
	}
}

// LogMode 设置日志级别
func (l *GormLogger) LogMode(level gormLogger.LogLevel) gormLogger.Interface {
	newLogger := *l
	newLogger.LogLevel = level
	return &newLogger
}

// Info 记录信息日志
func (l *GormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
	if l.LogLevel >= gormLogger.Info {
		l.logger.Infof(msg, data...)
	}
}

// Warn 记录警告日志
func (l *GormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
	if l.LogLevel >= gormLogger.Warn {
		l.logger.Warnf(msg, data...)
	}
}

// Error 记录错误日志
func (l *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
	if l.LogLevel >= gormLogger.Error {
		l.logger.Errorf(msg, data...)
	}
}

// Trace 记录SQL跟踪信息
func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
	if l.LogLevel <= gormLogger.Silent {
		return
	}

	elapsed := time.Since(begin)
	sql, rows := fc()

	// 添加文件位置信息
	fileInfo := utils.FileWithLineNum()

	// 构建日志消息
	logFields := map[string]interface{}{
		"elapsed": elapsed.String(),
		"rows":    rows,
		"sql":     sql,
		"file":    fileInfo,
	}

	switch {
	case err != nil && (!errors.Is(err, gorm.ErrRecordNotFound) || !l.IgnoreRecordNotFoundError):
		// 错误日志
		logFields["error"] = err.Error()
		if rows == -1 {
			l.logger.With(logFields).Errorf("SQL执行错误 [%.3fms]", float64(elapsed.Nanoseconds())/1e6)
		} else {
			l.logger.With(logFields).Errorf("SQL执行错误 [%.3fms] [%d rows]", float64(elapsed.Nanoseconds())/1e6, rows)
		}

	case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= gormLogger.Warn:
		// 慢查询日志
		slowLog := fmt.Sprintf("慢SQL警告 >= %v", l.SlowThreshold)
		if rows == -1 {
			l.logger.With(logFields).Warnf("%s [%.3fms]", slowLog, float64(elapsed.Nanoseconds())/1e6)
		} else {
			l.logger.With(logFields).Warnf("%s [%.3fms] [%d rows]", slowLog, float64(elapsed.Nanoseconds())/1e6, rows)
		}

	case l.LogLevel == gormLogger.Info:
		// 普通查询日志（Debug级别 - 生产环境通过配置控制）
		if rows == -1 {
			l.logger.With(logFields).Debugf("SQL [%.3fms]", float64(elapsed.Nanoseconds())/1e6)
		} else {
			l.logger.With(logFields).Debugf("SQL [%.3fms] [%d rows]", float64(elapsed.Nanoseconds())/1e6, rows)
		}
	}
}

// gormLogWriter 保留原有的简单适配器（向后兼容）
type gormLogWriter struct {
	logger logger.Logger
}

// Printf 实现 gormLogger.Writer 接口（简单模式）
func (w *gormLogWriter) Printf(format string, args ...interface{}) {
	msg := fmt.Sprintf(format, args...)

	// 简单的级别判断
	if strings.Contains(msg, "ERROR") || strings.Contains(msg, "error") {
		w.logger.Error(msg)
	} else if strings.Contains(msg, "SLOW SQL") || strings.Contains(msg, "slow") {
		w.logger.Warn(msg)
	} else {
		w.logger.Debug(msg)
	}
}
